package com.bowlong.third.payment.apple;

import java.nio.charset.Charset;
import java.util.Map;
import java.util.Set;

import com.bowlong.json.JSON;
import com.bowlong.net.http.HttpEx;
import com.bowlong.util.MapEx;
import com.bowlong.util.NewSet;
import com.bowlong.util.Ref;

@SuppressWarnings("rawtypes")
public class IAP {
	static final Charset UTF8 = Charset.forName("UTF-8");
	static final String APP_STORE = "https://buy.itunes.apple.com/verifyReceipt"; // 正式验证地址
	static final String APP_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt"; // 沙盒验证地址

	static final Set<String> transactions = new NewSet<String>();

	public static boolean checkOrder(String startsWithProductId, byte[] post) {
		Ref<String> errMsg = new Ref<String>("");
		boolean r2 = checkStore(startsWithProductId, post, errMsg);
		if (!r2) { // 检测不过，用沙盒再试
			r2 = checkSandbox(startsWithProductId, post, errMsg);
		}
		return r2;
	}

	public static boolean checkStore(String startsWithProductId, byte[] post,
			Ref<String> errMsg) {
		return checkStore(APP_STORE, startsWithProductId, post, errMsg);
	}

	public static boolean checkSandbox(String startsWithProductId, byte[] post,
			Ref<String> errMsg) {
		return checkStore(APP_SANDBOX, startsWithProductId, post, errMsg);
	}

	public static boolean checkStore(String szURL, String startsWithProductId,
			byte[] post, Ref<String> errMsg) {
		byte[] recv = null;
		try {
			recv = HttpEx.readUrl(szURL, post);
		} catch (Exception e) {
			errMsg.val = e.getMessage();
			return false;
		}
		String sRecv = new String(recv, UTF8);
		Map receipt_ret = JSON.toMap(sRecv);

		if (receipt_ret == null || receipt_ret.isEmpty()) {
			errMsg.val = "receipt_ret: error";
			return false;
		}

		int status = MapEx.getInt(receipt_ret, "status");
		if (status != 0) {
			errMsg.val = "status:" + status + " error";
			return false;
		}

		Map receipt = MapEx.getMap(receipt_ret, "receipt");
		if (receipt == null) {
			errMsg.val = "receipt:" + receipt + " null";
			return false;
		}
		String product_id = MapEx.getString(receipt, "product_id");
		if (!product_id.startsWith(startsWithProductId)) {
			errMsg.val = "productId:" + startsWithProductId + " false";
			return false;
		}

		String transactionId = MapEx.getString(receipt, "transaction_id");
		if (transactions.contains(transactionId)) {
			errMsg.val = "transactionId:" + transactionId + " repeat";
			return false;
		}
		transactions.add(transactionId);
		errMsg.val = "succ";
		return true;
	}
}
